﻿//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "stdafx.h"
#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	GetNuendoHandle();
	ShowMidiDevice();
	srand( time(NULL) );  //一開始執行過一次就好

    InitialGlobalVariables();
	CalculateEmotionProb();
	CalculateGuitarProb();

	Form1->EmotionModelGroup->Parent->DoubleBuffered = true;

	CurrentTempo = Form1->TempoBar->Position;
	DesireTempo[0] = Form1->TempoBar->Position;
	DesireTempo[1] = Form1->TempoBar->Position;
	paint_EmotionMap();
	paint_Bar(false);

	SetNuendoTempo( StrToInt(Form1->TempoEdit->Text) );
	TimerBeginPeriod();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
	TimerEndPeriod();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TempoBarChange(TObject *Sender)
{
	/*
	音樂速度一般都會以文字或數字標記於一首樂曲的開端，
	現代習慣以每分鐘多少拍（beats per minute，簡稱BPM）作單位。
	這表示一個指定的音符，例如四分音符在一分鐘內出現的次數。
	120是其BPM值，表示每分鐘演奏120個四分音符，
	即每個四分音符的長度等於1分鐘除以120等分＝0.5秒
	*/

	Form1->TempoEdit->Text = IntToStr(Form1->TempoBar->Position);
	Form1->TempoUpDown->Position = Form1->TempoBar->Position;

	if(Form1->StartBtn->Enabled)  //如果現在是沒有在跑得時候才從這裡改速度
	{
		SetNuendoTempo( StrToInt(Form1->TempoEdit->Text) );
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::TempoUpDownClick(TObject *Sender, TUDBtnType Button)
{
	Form1->TempoBar->Position = Form1->TempoUpDown->Position;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::MidiPortConnectBtnClick(TObject *Sender)
{
	//取得目前使用者選擇的Device
	//char* OutputSelect = (char*)(void*)Marshal::StringToHGlobalAnsi( this->MidiOutBox->Text );

	//if( strcmp( "Microsoft GS Wavetable Synthetizer" , OutputSelect ) == 0 )  //如果選擇的是Microsoft
	if(Form1->MidiPortSelectCombo->Text == "Microsoft GS Wavetable Synthetizer")
	{
		for (int i=0; i<DevNum; i++)  //跑所有的Device
		{
			midiOutClose(device[i]);
			//midiOutOpen(&device[i], MicroDeviceNum, 0, 0, CALLBACK_NULL);
		}
		midiOutOpen(&device[0], MicroDeviceNum, 0, 0, CALLBACK_FUNCTION);

		for (int i=1; i<DevNum; i++)  //跑所有的Device
		{
			device[i] = device[0];
		}

		//MessageBox::Show( Convert::ToString(MicroDeviceNum) );
	}
	//else if( strcmp( "GigaStudio Output" , OutputSelect ) == 0 )  //如果選擇的是GigaStudio
	else if(Form1->MidiPortSelectCombo->Text == "LoopMidi Port")
	{
		for (int i=0; i<DevNum; i++)  //跑所有的Device
		{
			midiOutClose(device[i]);
			midiOutOpen(&device[i], GigaDeviceNum + i, 0, 0, CALLBACK_NULL);
		}
		//MessageBox::Show( Convert::ToString(GigaDeviceNum) );
	}

}
//---------------------------------------------------------------------------

void __fastcall TForm1::MidiPortSelectComboChange(TObject *Sender)
{
	TForm1::MidiPortConnectBtnClick(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::NoteOnBtnClick(TObject *Sender)
{
	MidiNoteOn(21, 57, 100);
	MidiNoteOff(21, 57, 100);
	for(int i=13; i<=20; i++)
	{
		MidiNoteOn(i, 36, 100);
		MidiNoteOff(i, 36, 100);
	}

	if(Form1->NotePortCombobox->Text == "All Port")
	{
		for(int i=0; i<DevNum; i++)
		{
			MidiNoteOn(i, StrToInt(Form1->NoteOnOffPitchEdit->Text), Form1->NoteVelocityBar->Position);
		}
	}
	else
	{
		MidiNoteOn(Form1->NotePortCombobox->ItemIndex, StrToInt(Form1->NoteOnOffPitchEdit->Text), Form1->NoteVelocityBar->Position);
	}
}
//--------------------------------------------------------------------------

void __fastcall TForm1::NoteOffBtnClick(TObject *Sender)
{
	if(Form1->NotePortCombobox->Text == "All Port")
	{
		for(int i=0; i<DevNum; i++)
		{
			MidiNoteOff(i, StrToInt(Form1->NoteOnOffPitchEdit->Text), Form1->NoteVelocityBar->Position);
		}
	}
	else
	{
		MidiNoteOff(Form1->NotePortCombobox->ItemIndex, StrToInt(Form1->NoteOnOffPitchEdit->Text), Form1->NoteVelocityBar->Position);
	}

	MidiNoteOn(21, 36, 100);  //Bass Off
	MidiNoteOff(21, 36, 100);
	MidiNoteOn(22, 71, 100);  //Groove Off
	MidiNoteOff(22, 71, 100);
	MidiNoteOn(23, 71, 100);  //Groove2 Off
	MidiNoteOff(23, 71, 100);

	MuteAllNote();   //把所有Note關掉
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ChordOnBtnClick(TObject *Sender)
{
	MidiNoteOn(21, 57, 100);
	MidiNoteOff(21, 57, 100);
	for(int i=13; i<=20; i++)
	{
		MidiNoteOn(i, 36, 100);
		MidiNoteOff(i, 36, 100);
	}

	if(Form1->NotePortCombobox->Text == "All Port")
	{
    	for(int i=0; i<DevNum; i++)
		{
			PlayOneChord("Play", i, StrToInt(Form1->NoteOnOffPitchEdit->Text), 1, Form1->ChordCombobox->Text, Form1->NoteVelocityBar->Position);
		}
	}
	else
	{
		PlayOneChord("Play", Form1->NotePortCombobox->ItemIndex, StrToInt(Form1->NoteOnOffPitchEdit->Text), 1, Form1->ChordCombobox->Text, Form1->NoteVelocityBar->Position);
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ChordOffBtnClick(TObject *Sender)
{
	if(Form1->NotePortCombobox->Text == "All Port")
	{
    	for(int i=0; i<DevNum; i++)
		{
			PlayOneChord("Mute", i, StrToInt(Form1->NoteOnOffPitchEdit->Text), 1, Form1->ChordCombobox->Text, Form1->NoteVelocityBar->Position);
		}
	}
	else
	{
		PlayOneChord("Mute", Form1->NotePortCombobox->ItemIndex, StrToInt(Form1->NoteOnOffPitchEdit->Text), 1, Form1->ChordCombobox->Text, Form1->NoteVelocityBar->Position);
	}

	MidiNoteOn(21, 36, 100);  //Bass Off
	MidiNoteOff(21, 36, 100);
	MidiNoteOn(22, 71, 100);  //Groove Off
	MidiNoteOff(22, 71, 100);
	MidiNoteOn(23, 71, 100);  //Groove2 Off
	MidiNoteOff(23, 71, 100);

	MuteAllNote();   //把所有Note關掉
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Mixer1Click(TObject *Sender)
{
	FormMixer->Show();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::EmotionModelImageMouseDown(TObject *Sender, TMouseButton Button,
		  TShiftState Shift, int X, int Y)
{
	Mouse_Down = true;
	NeedFill = true;

	if( calculate_distance(AV2XY(AV_Point), XY2Point(X,Y)) < 15 )
	{
		AV_Point_Sel = true;
	}
	else
	{
    	AV_Point_Sel = false;
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::EmotionModelImageMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
{
	Mouse_Down = false;
	AV_Point_Sel = false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::EmotionModelImageMouseMove(TObject *Sender, TShiftState Shift,
		  int X, int Y)
{
	if(Mouse_Down && AV_Point_Sel)
	{
		AV_Point = XY2AV( XY2Point(X,Y) );
		AV_Point.x = AV_Point.x > 1 ? 1 : AV_Point.x;
		AV_Point.y = AV_Point.y > 1 ? 1 : AV_Point.y;
		AV_Point.x = AV_Point.x < -1 ? -1 : AV_Point.x;
		AV_Point.y = AV_Point.y < -1 ? -1 : AV_Point.y;

		DesireTempo[0] = XY2DesireTempo( XY2Point(X,Y) );    //Current

		CalculateEmotionProb();
		CalculateGuitarProb();

		paint_EmotionMap();
	}

	position_store AVValue = XY2AV( XY2Point(X,Y) );
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RuleTable1Click(TObject *Sender)
{
	FormFuzzy->Show();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Enable1Click(TObject *Sender)
{
	Form1->Fixed1->Checked = false;
	Form1->Enable1->Checked = true;
	Form1->Disable1->Checked = false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Disable1Click(TObject *Sender)
{
	Form1->Fixed1->Checked = false;
	Form1->Enable1->Checked = false;
	Form1->Disable1->Checked = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Fixed1Click(TObject *Sender)
{
	Form1->Fixed1->Checked = true;
	Form1->Enable1->Checked = false;
	Form1->Disable1->Checked = false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ChangeTimerTimer(TObject *Sender)
{
	SetVol();

	/////////////////////計算速度////////////////////
	fuzzy_decision();

	if( Form1->Enable1->Checked )   //Use Fuzzy
	{
		if( Float_Abs(Fuzzy_output) >= 0.3 )
		{
			CurrentTempo += Fuzzy_output;
			Form1->TempoBar->Position = CurrentTempo;
		}
	}
	else if( Form1->Disable1->Checked )
	{
		CurrentTempo = DesireTempo[0];
		Form1->TempoBar->Position = DesireTempo[0];
	}
	DesireTempo[1] = DesireTempo[0];  //Last

	if(Form1->StopBtn->Enabled) //如果有在跑
	{
		paint_Nototion();   //畫出現在的狀況
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StartBtnClick(TObject *Sender)
{
	Form1->StartBtn->Enabled = false;
	Form1->StopBtn->Enabled = true;

	ActualTempo = Form1->TempoBar->Position;
	TimePosition = -OneSectionNoteNum;
	BarTimerStart();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::StopBtnClick(TObject *Sender)
{
	Form1->StartBtn->Enabled = true;
	Form1->StopBtn->Enabled = false;

	MidiNoteOn(21, 36, 100);  //Bass Off
	MidiNoteOff(21, 36, 100);
	MidiNoteOn(22, 71, 100);  //Groove Off
	MidiNoteOff(22, 71, 100);
	MidiNoteOn(23, 71, 100);  //Groove2 Off
	MidiNoteOff(23, 71, 100);

	MuteAllNote();   //把所有Note關掉

	//Form1->BarTimer->Enabled = false;
	BarTimerStop();
	TimePosition = 0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ShowNotationExecute(TObject *Sender)
{
	Form1->Width = 1238;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::HideNotationExecute(TObject *Sender)
{
	Form1->Width = 750;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta,
          TPoint &MousePos, bool &Handled)
{
//	if (WheelDelta == WHEEL_DELTA)
//	{
//		Form1->NotationScrollBox->VertScrollBar->Position -= 30;
//	}
//	else if (WheelDelta == -WHEEL_DELTA)
//	{
//		Form1->NotationScrollBox->VertScrollBar->Position += 30;
//	}
}
//---------------------------------------------------------------------------



void __fastcall TForm1::LearningPerformanceTest1Click(TObject *Sender)
{
	FormLearning->Show();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ShowFormLearningExecute(TObject *Sender)
{
	FormLearning->Show();
}
//---------------------------------------------------------------------------

